﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;



namespace DispositifAffichage2
{
    public class Communication2
    {
        int bin_width = 1500;
        int bin_height = 1000;

        private int chrono = 1;

        public int Chrono
        {
            get
            {
                return chrono;
            }
        }






        Rectangle[] best_rects3;

        //List<Rectangle> rects3 = new List<Rectangle>();
        Algorithms alg;
        List<Rectangle> zrects = new List<Rectangle>();
        Rectangle[] rectsFinal;
        List<Rectangle> rectsFinallist = new List<Rectangle>();
        string[] resultat3 = new string[3];
        Dictionary<string, Rectangle> dictionary = new Dictionary<string, Rectangle>();
        Dictionary<string, Rectangle> dictionaryFinal = new Dictionary<string, Rectangle>();

        private string nom;

        private string nom2;
        Boolean same = true;
        private int width;
        private int height;
        //cmp pour modifier le nom de key de dictionnary
        static int cmp = 0;

        ServeurDispositifAffichage serv;

        public Communication2(/*ServeurDispositifAffichage serveur*/)
        {


        }

        public Communication2(ServeurDispositifAffichage serveur)
        {

            serv = serveur;

            alg = new Algorithms(this);
        }

        public void getResult(Rectangle[] res)
        {

            rectsFinal = res;

            //best solution
            Console.WriteLine("Début5");
            for (int q = 0; q < rectsFinal.Length; q++)
            {

                Console.WriteLine("W = " + rectsFinal[q].Width);
                Console.WriteLine("H = " + rectsFinal[q].Height);
                Console.WriteLine("X = " + rectsFinal[q].X);
                Console.WriteLine("Y = " + rectsFinal[q].Y);
            }

            Console.WriteLine("Fin5");



        }

        // Load data, run an algorithm, and display the results.
        public string compare(string name, int width1, int height1)
        {
            string resultat = "";

            nom = name;
            nom2 = name;
            width = width1;
            height = height1;
            Console.WriteLine("nom est= " + nom);

            if (height <= bin_height && width <= bin_width)
            {

                Rectangle rec = new Rectangle(0, 0, width, height);
                //rects3.Add(rec);

                if (dictionary.ContainsKey(nom))
                {

                    nom += "I" + cmp;
                    Console.WriteLine("Name Après modification est = " + nom);
                    cmp++;
                }


                try
                {
                    dictionary.Add(nom, rec);
                }
                catch (ArgumentException)
                {
                    Console.WriteLine("Un élément possède déjà la clé \"txt\".");
                }
                /*
                                Console.WriteLine("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");

                                foreach (KeyValuePair<string, Rectangle> kvp in dictionary)
                                {
                                    Console.WriteLine("Key = {0}, Value = {1}", kvp.Key,kvp.Value);
                                }

                                Console.WriteLine("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");

                                */

                Rectangle[] rects = dictionary.Values.ToArray();

                Console.WriteLine("Début000000000000000000000000000000000000000000000000");
                for (int q = 0; q < rects.Length; q++)
                {

                    Console.WriteLine("W = " + rects[q].Width);
                    Console.WriteLine("H = " + rects[q].Height);
                    Console.WriteLine("X = " + rects[q].X);
                    Console.WriteLine("Y = " + rects[q].Y);
                }

                Console.WriteLine("Fin000000000000000000000000000000000000000000000000000");

                //Rectangle[] rects = rects3.ToArray();
                //appel de l'algorithme 
                alg.AlgFillByStripes(bin_width, bin_height, rects);


                // Display the results.
                Boolean b = DisplayResults(rec, rectsFinal);

                if (b == false)
                {
                    resultat = "Non, je ne peux pas afficher votre interface";

                    dictionary.Remove(nom);
                }

                else
                {

                    //b=true : soit True soit Oui peut être, cas de Oui, peut être est défini par zrects.Count>0 AND same=True

                    //cas de True, j'ajoute les nouvelles dimensions (width, height) à mon dictionnary et je met à jour les autres positionnements

                    rectsFinallist = rectsFinal.ToList();
                    Console.WriteLine("LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL");
                    /*
                                        for (int l = 0; l < rectsFinallist.Count; l++)
                                        {

                                            Console.WriteLine("Width**************** " + rectsFinallist[l].Width);
                                            Console.WriteLine("Height*************** " + rectsFinallist[l].Height);
                                            Console.WriteLine("X**************** " + rectsFinallist[l].X);
                                            Console.WriteLine("Y**************** " + rectsFinallist[l].Y);

                                        }
                                        */
                    Console.WriteLine("LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL");

                    //Ajout de nouvelles dimensions(width, height) : dictionnaryFinal.Add()

                    for (int j = 0; j < rectsFinal.Length; j++)
                    {

                        if (rectsFinal[j].Width == width && rectsFinal[j].Height == height)
                        {

                            Console.WriteLine("Width:::::::::::: " + width);
                            Console.WriteLine("Height:::::::::::: " + height);
                            Console.WriteLine("X:::::::::::: " + rectsFinal[j].X);
                            Console.WriteLine("Y:::::::::::: " + rectsFinal[j].Y);
                            Rectangle rectest = new Rectangle(rectsFinal[j].X, rectsFinal[j].Y, width, height);

                            try
                            {
                                dictionaryFinal.Add(nom, rectest);
                            }
                            catch (ArgumentException)
                            {
                                Console.WriteLine("Un élément possède déjà la clé \"txt\".");
                            }
                        }


                    }



                    /*for (int i = 0; i < rectsFinallist.Count; i++) {
                    
                    Rectangle xrects=rectsFinallist[i];

                    foreach (KeyValuePair<string, Rectangle> kvp in dictionaryFinal)
                    {
                        string name2 = kvp.Key;
                        if(xrects.Width==kvp.Value.Width && xrects.Height== kvp.Value.Height){

                            
                            dictionaryFinal.Remove(name2);

                            try {
                                
                                dictionaryFinal.Add(name2,xrects);
                            }
                            catch (ArgumentException)
                            {
                                Console.WriteLine("Un élément possède déjà la clé \"txt\".");
                            }

                            break;
                        }
                    
                        
                    }
                    
                    }*/


                    Console.WriteLine("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS");
                    //mettre à jour 

                    List<string> keylist = new List<string>();

                    try
                    {
                        foreach (KeyValuePair<string, Rectangle> kvv in dictionaryFinal)
                        {
                            string name2 = kvv.Key;
                            Boolean existe = false;

                            for (int i = 0; i < rectsFinallist.Count; i++)
                            {

                                Rectangle xrects = rectsFinallist[i];

                                if (xrects.Width == kvv.Value.Width && xrects.Height == kvv.Value.Height)
                                {

                                    existe = true;

                                    dictionaryFinal.Remove(name2);

                                    try
                                    {

                                        dictionaryFinal.Add(name2, xrects);
                                    }
                                    catch (ArgumentException)
                                    {
                                        Console.WriteLine("Un élément possède déjà la clé \"txt\".");
                                    }

                                    break;
                                }

                            }

                            if (existe == false) { keylist.Add(name2); }
                        }

                    }
                    catch (InvalidOperationException) { Console.WriteLine("OOOOOOOOOOOOOOOPPPPPPPPSSSSSSSSSSS"); }

                    rectsFinallist.Clear();

                    for (int j = 0; j < keylist.Count; j++)
                    {

                        dictionaryFinal.Remove(keylist[j]);

                    }

                    keylist.Clear();
                    Console.WriteLine("SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS");



                    Console.WriteLine("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

                    foreach (KeyValuePair<string, Rectangle> kvp in dictionaryFinal)
                    {
                        Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
                    }

                    Console.WriteLine("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
                    Console.WriteLine("111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");
                    Console.WriteLine("zrects.Count est : " + zrects.Count);
                    Console.WriteLine("111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111");

                    if (zrects.Count > 0)
                    {
                        //cas de Oui, peut être
                        Console.WriteLine("@@@@@@@@@@  zrects contient des élèments  @@@@@@@@@@");
                        //voir si ces éléments ont le même key que la nouvelle interface que je veux l'affichée
                        /*
                             same = true;

                             for (int k = 0; k < zrects.Count;k++ ) { 
                        
                                     Rectangle xrects=zrects[k];

                             foreach (KeyValuePair<string, Rectangle> kvp in dictionary)
                             {

                                 Rectangle theElement = kvp.Value;

                                 if(xrects.Height==theElement.Height && xrects.Width==theElement.Width){
                            
                                 string id = kvp.Key;

                                 if (!id.Contains(name)) { 
                                    same = false; 
                                 }
                                 Console.WriteLine("YYYYYYYYYYYYYYYYYYYYYYYYYOOOOOOOOOOOOOOOOOOOOOOOO  key: " + kvp.Key);
                                 }
                            
                             } 
                             }
                             */

                        if (same)
                        {

                            string s = "";
                            Console.WriteLine("8888888888888888888888888888888888888888888888888888888888888888888888888888888888");
                            for (int a = 0; a < zrects.Count; a++)
                            {
                                s += "Width= " + zrects[a].Width.ToString() + " et Height= " + zrects[a].Height.ToString() + "\n";
                                Console.WriteLine("zrects[a].Width= " + zrects[a].Width);
                                Console.WriteLine("zrects[a].Height= " + zrects[a].Height);
                                Console.WriteLine("zrects[a].X= " + zrects[a].X);
                                Console.WriteLine("zrects[a].Y= " + zrects[a].Y);


                            }
                            Console.WriteLine("8888888888888888888888888888888888888888888888888888888888888888888888888888888888");
                            Console.WriteLine("s= " + s);

                            resultat = "Oui,peut être, pour afficher l'interface on peut la mettre à la place de l'interface de: \n" + s + ",\nTon Identifiant de Reservation = " + nom;
                            serv.getdictionaryFinal(dictionaryFinal);

                        }



                        else { resultat = "Non, je ne peux pas afficher votre interface"; }

                        zrects.Clear();

                    }

                    else
                    {
                        Console.WriteLine("@@@@@@@@@@  zrects ne contient pas des élèments  et b =True @@@@@@@@@@");
                        resultat = "Oui, je peux afficher votre interface, \nTon Identifiant de Reservation = " + nom;

                        best_rects3 = new Rectangle[rectsFinal.Length];
                        best_rects3 = rectsFinal;

                        //envoyer le resultatFinal (le dictionnary dictionnaryFinal) 

                        serv.getdictionaryFinal(dictionaryFinal);


                    }
                }




                Console.WriteLine("Resultat= " + resultat);

                //test sur le résultat si "Oui" ou "Oui, peut être" on lui donne un IdReservation=nom

                //aussi il faut enregistrer le resultat final rectsFinal sous forme d'un dictionnary(key, valeur)

                return resultat;

            }

                //cas de height > bin_height && width > bin_width
            else return "Non, je ne peux pas afficher votre interface";

        }


        private delegate void Algorithm(int bin_width, int bin_height, Rectangle[] rects);


        // Display the results.

        public Boolean DisplayResults(Rectangle rec, Rectangle[] rects)
        {
            //Console.WriteLine("W= " + rec.Width);
            //Console.WriteLine("H= " + rec.Height);

            if (chrono == 1)
            {
                //1ére interface à afficher

                best_rects3 = new Rectangle[rects.Length];
                Array.Copy(rects, best_rects3, rects.Length);

                chrono++;
                return true;

            }


            else
            {

                Console.WriteLine("chrono= " + chrono);

                for (int q = 0; q < best_rects3.Length; q++)
                {

                    Console.WriteLine("WW = " + best_rects3[q].Width);
                    Console.WriteLine("HH = " + best_rects3[q].Height);
                    Console.WriteLine("XX = " + best_rects3[q].X);
                    Console.WriteLine("YY = " + best_rects3[q].Y);

                }

                for (int q = 0; q < rects.Length; q++)
                {

                    Console.WriteLine("WW rects = " + rects[q].Width);
                    Console.WriteLine("HH rects = " + rects[q].Height);
                    Console.WriteLine("XX rects = " + rects[q].X);
                    Console.WriteLine("YY rects = " + rects[q].Y);

                }
                Console.WriteLine("lenght rects= " + rects.Length);
                Console.WriteLine("lenght best_rects3= " + best_rects3.Length);


                //n éme interface à afficher
                if (rects.Length > best_rects3.Length)
                {
                    //resultat=True
                    return true;
                }

                else
                {
                    //si length <=


                    for (int k = 0; k < best_rects3.Length; k++)
                    {
                        Boolean trouve = false;

                        for (int z = 0; z < rects.Length; z++)
                        {
                            if (best_rects3[k].Width == rects[z].Width && best_rects3[k].Height == rects[z].Height) { trouve = true; }

                        }

                        if (trouve == false)
                        {

                            zrects.Add(best_rects3[k]);
                        }

                    }

                    if (zrects.Count > 0)
                    {
                        //case Oui/peut être


                        same = true;

                        for (int k = 0; k < zrects.Count; k++)
                        {

                            Rectangle xrects = zrects[k];

                            foreach (KeyValuePair<string, Rectangle> kvp in dictionary)
                            {

                                Rectangle theElement = kvp.Value;

                                if (xrects.Height == theElement.Height && xrects.Width == theElement.Width)
                                {

                                    string id = kvp.Key;

                                    Console.WriteLine("NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOMMMMMMMMMMMMMMMMMMM EST =" + nom2);
                                    if (!nom2.Contains(id))
                                    {
                                        same = false;
                                    }
                                    Console.WriteLine("YYYYYYYYYYYYYYYYYYYYYYYYYOOOOOOOOOOOOOOOOOOOOOOOO  key: " + kvp.Key);
                                }

                            }
                        }

                        if (same)
                        {
                            //resultat=Oui peut être
                            return true;
                        }

                        else return false;




                    }
                    //les mêmes membres dans les deux rects
                    else { return false; }



                }



            }


        }


        //get decision final pour le resultat Oui/peut être
        public void updateResultatFinal()
        {

            rectsFinal = new Rectangle[best_rects3.Length];
            rectsFinal = best_rects3;

            Console.WriteLine("nom pour la deuxième fois est = " + nom);
            dictionary.Remove(nom);
            dictionaryFinal.Remove(nom);


            serv.getdictionaryFinal(dictionaryFinal);
        }


        public void updateResultatFinal2()
        {

            rectsFinal = new Rectangle[best_rects3.Length];
            rectsFinal = best_rects3;
            Console.WriteLine("chrono !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! " + Chrono);
            Console.WriteLine("nom pour la deuxième fois est !!!!! = " + nom);

            if (chrono == 2)
            {
                Console.WriteLine("Oui chrono=2");
                best_rects3 = new Rectangle[0];
                rectsFinal = best_rects3;
                zrects.Clear();
                chrono = 1;
                //Array.Copy(rects, best_rects3, rects.Length);
            }
            dictionary.Remove(nom);
            dictionaryFinal.Remove(nom);
            serv.getdictionaryFinal(dictionaryFinal);
        }

    }
}
